<?php
/**************************************************
 *    name: ModelBase
 *    说明: 模型基础类，定义通用的方法
 *  author: fenghao
 *    date: 2012-04-23
 *  update: 2012-11-30 添加插入单条记录，并返回对应id的方法
 * 	        2012-12-19 添加ReplaceData方法 和 UpdateRecord方法
 *          2013-01-16 和MC_Model类整合在一起
 **************************************************/

class ModelBase {
	
    /**
     * @var object 数据库对象单例
     */
    static $_instanceDB = NULL;
    /**
     * @var 控制器对象
     */
    public $controller = NULL;
    /**
     * @var config 数组 
     */
    public $config = NULL;
    /**
     * @var 模型层对象
     */
    public $model = NULL;
    /**
     * @var 数据库对象
     */
    public $db  = NULL;

    /**
     * @var 当前model对应的数据表
     */
    protected $tab = '';
	
    /**
     * @var 当前error log
     */
    protected $err = '';

	/**
	 * 对应的字段名称
	 */
	private $fields = array();
    
    /**
     * Model构造函数
     *
     * @param string $controllerName 控制器名
     * @return void
     */
	 //2013-01-16 更新，不传递controller实例
    public function __construct($controller=null){
		//2013-01-15 更新
		//可以不传递controller，默认使用系统中保存的config数组
		
		if (is_object($controller)){
			$this->controller = $controller;
			$this->config = $this->controller->config;
        }else{
			$this->config = __get_config();
		}
		if(!is_array($this->config) || empty($this->config)){
			throw new MC_Exception("MC_Model: Config array is not seted.");
		}
        $this->db = $this->getDb();
        if(!is_object($this->db)){
			$this->err = "MC_Modle:(". __CLASS__ . ") 数据库错误，请稍候再试 ( ".$this->db->getError()." )";
            throw new MC_Exception($this->err);
        }
        $this->db->query("set names ". $this->config['DataBase']['charset']);

    }
	
	
    /**
     * 获取数据库访问对象
     *
     * @param void
     * @return object
     */
    public function getDb(){
		if(is_object(self::$_instanceDB)){
			return self::$_instanceDB;
		}
        //定位数据库访问类
        $driver = $this->config['DataBase']['driver']=='' ? "DB_Mysqli" : $this->config['DataBase']['driver'];
        $class  = "MC_". $driver;

        //初始化数据库访问
        $dbConfig = array(
            "host"  => $this->config['DataBase']['host'],
            "user"  => $this->config['DataBase']['user'],
            "pwd"   => $this->config['DataBase']['pwd'],
            "db"    => $this->config['DataBase']['db'],
        );
        self::$_instanceDB = new $class($dbConfig);
		$this->db = self::$_instanceDB;

        return $this->db;
    }

	
    /**
     * 数据库操作: 添加页面
     * @param array $field_array 字段数组array( '字段1'=>'数据1', 'key2'=>'value2', .... ) 
     * @return int
     * 成功返回 1, 失败返回false
     */
	function CreateData($fields = array()){
        if(is_array($fields) && !empty($fields)){
            
            //添加数据
            $result = $this->db->insert($fields, $this->tab);
            if($result === false){
				$this->err = "MC_Modle:(". __CLASS__ . ") 数据添加失败，请稍候再试 ( ".$this->db->getError()." )";
            throw new MC_Exception($this->err);
            }
            //$this->db->unlockTable($this->tab);
            return $result;
        }else{
            return false;
        }
            
	}

    /**
     * 数据库操作：添加单条记录
     * @param array $field_array 字段数组array( 'user_name'=>'name', 'user_pass'=>'pass', .... )
     * @return int
     * 成功返回 id, 失败返回false
     */
    function AddRecord($info = array()){
        if(!empty($info) && is_array($info)){
            
			//锁定表
			
			if($this->db->lockTable($this->tab, "WRITE")){
            //$this->db->lockTable( $this->tab);
            
				//添加数据
				$result = $this->db->insert($info, $this->tab);
				
				//
				//$_SESSION['uid'] = $this->db->getRow("select uid from ".$this->tab." where uname = '".$_userdata['uname']."'"); 
				
				if($result === false){
					$this->err = "MC_Modle:(". __CLASS__ . ") 记录添加失败，请稍候再试 ( ".$this->db->getError()." )";
					throw new MC_Exception($this->err);
				}
				//$this->db->unlockTable($this->tab);
				else{
					$id = $this->db->getLastId();
					
				}
				$this->db->unlockTable($this->tab);
				return $id;
			}else{
				$this->err = "MC_Modle:(". __CLASS__ . ") 记录添加失败，请稍候再试 ( ".$this->db->getError()." )";
				throw new MC_Exception($this->err);
			}
				
        }else{
            return false;
        }
            
    }
	
    /**
     * 数据库操作：给定数值，如果数据存在，返回对应的记录; 如果不存在，更新数据
     * @param array $info 需要更新字段数组array( 'user_name'=>'name', 'user_pass'=>'pass' ) 
     * @return mixed
     * 成功返回具体记录（记录存在）或者记录的ID（记录不存在），失败返回false
     */
    public function UpdateRecord($info=array()){
        if(!empty($info) && is_array($info)){
			$result = $this->GetData($info);
			if($result != null){
				return $result;
			}else{
				return $this->AddRecord($info);
			}
        }else{
            return false;
        }
	}
	
	
    /**
     * 数据库操作：给定数值，更新数据 repalce
     * @param array $info 需要更新字段数组array( 'user_name'=>'name', 'user_pass'=>'pass' ) 
     * @return mixed
     * 成功返回受影响的行数，失败返回false
     */
    public function ReplaceData($info=array()){
        if(!empty($info) && is_array($info)){
			//sql语句
			$sqlcmd = "REPLACE INTO `".$this->tab."` SET ";
			foreach ($info as $key => $value){   
				$sqlcmd .= " `$key`='$value',";   
			}   
			$sqlcmd = rtrim($sqlcmd, ',');   
			$result = $this->db->execute($sqlcmd);
			if($result === false){
				$this->err = "MC_Modle:(". __CLASS__ . ") 数据更新失败，请稍候再试 ( ".$this->db->getError()." )";
				throw new MC_Exception($this->err);
			}
			return $result;
        }else{
            return false;
        }
    }
	
	
    /**
     * 数据库操作：给定条件，更新数据
     * @param array $update_field 需要更新字段数组array( 'user_name'=>'name', 'user_pass'=>'pass' ) 
     * @param mixed $condition_field 条件字符串 或
     *              $condition_field 条件数组 array('cond1'=>'va1', 'cond2'=>'va2');
     *              当一个条件给定多个值是可以使用如下方式 array('id'=>array(id1,id2,....), cond2=>array(v1,v2,....)
     * @return mixed
     * 成功返回受影响的行数，失败返回false
     */
    function UpdateData($update_field, $condition_field){
        //处理条件
        $where = SqlFuncs::getSqlCondition($condition_field);
        
        if(!empty($update_field) && is_array($update_field)){

            //$this->db->lockTable( $this->tab, "WRITE" );

            $result = $this->db->update($update_field, $where, $this->tab); 

            if($result === false){
				$this->err = "MC_Modle:(". __CLASS__ . ") 数据更新失败，请稍候再试 ( ".$this->db->getError()." )";
            	throw new MC_Exception($this->err);
            }
            //$this->db->unlockTable($this->tab);
            return $result;
            
        }
        return false;
    }

    /**
     * 数据库操作：给定用户名或者用户id，返回用户数据
     * @param mixed $condition_field 条件字符串 或
     *              $condition_field 条件数组 array('cond1'=>'va1', 'cond2'=>'va2');
     *              当一个条件给定多个值是可以使用如下方式 array('id'=>array(id1,id2,....), cond2=>array(v1,v2,....)
     * @param mixed $query_field 需要返回的字段 可以是字符串，默认是 "*"， 或者数组 array( 'user_name'=>'name', 'user_pass'=>'pass', .... )
     * @param array $order_field 需要排序的字段 array( 'user_name'=>'ASC', 'user_pass'=>'DESC', .... ) 
     * @param array $limit_field 需要返回的条数 array($limit, $limit_start)
     * @return mix
     * 成功返回记录，没有找到返回null，失败返回false
     */
    function GetData($condition_field = null, $query_field = '*', $order_field=null, $limit_field=null){

        //sql语句
        $sqlcmd = "SELECT ";
        //处理查询字段
        $sqlcmd .=  SqlFuncs::getSqlQueryField($query_field);
        $sqlcmd .= " from ".$this->tab;
        //处理条件
        $where = SqlFuncs::getSqlCondition($condition_field);
        $sqlcmd .= $where?" WHERE $where ":" ";
        //处理排序
        $sqlcmd .= $order_field?SqlFuncs::getSqlOrder($order_field):"";
        //处理limit
        $sqlcmd .= $limit_field?(" Limit ". implode(", ",$limit_field)):"";
        $result = $this->db->getAll($sqlcmd);
        if($result === false){
			$this->err = "MC_Modle:(". __CLASS__ . ") 数据查询失败，请稍候再试 ( ".$this->db->getError()." )";
            throw new MC_Exception($this->err);
        }
        return $result;
    }


    /**
     * 数据库操作：删除给定条件的记录
     * @param mixed $condition_field 条件字符串 或
     *              $condition_field 条件数组 array('cond1'=>'va1', 'cond2'=>'va2');
     *              当一个条件给定多个值是可以使用如下方式 array('id'=>array(id1,id2,....), cond2=>array(v1,v2,....)
     * @return mix
     * 成功返回记录，没有找到返回null，失败返回false
     */
    function DelData($condition_field = null){
        
        //处理条件
        if(is_array($condition_field) && !empty($condition_field)){
            $where = SqlFuncs::getSqlCondition($condition_field);
        }else if($condition_field != null){
            $where = $condition_field;
        }else{
            return false;
        }

        //$this->db->lockTable( $this->tab, "WRITE");

        $result = $this->db->delete($where, $this->tab);

        if($result === false){
			$this->err = "MC_Modle:(". __CLASS__ . ") 数据删除失败，请稍候再试 ( ".$this->db->getError()." )";
            throw new MC_Exception($this->err);
        }
        //$this->db->unlockTable($this->tab);
        return $result;
    }
	
	/**
     * 数据库操作：查询总记录的总数
     * @param mixed $condition_field 字段数组array( 'user_name'=>'name', 'user_pass'=>'pass', .... )或者直接给定条件语句
     * @return 成功返回获取的一个整数值,失败返回false, 数据空返回NULL  
     */
	function getCount($condition_field = array()){
        //sql语句
        $sqlcmd = "SELECT COUNT(1) as cnt ";
        //处理查询字段
        //$sqlcmd .= " Count(pielink_id) AS `c`, boy, girl, seq ";
        $sqlcmd .= " FROM ".$this->tab;
        //处理条件
        $where = SqlFuncs::getSqlCondition($condition_field);
        $sqlcmd .= $where?" WHERE $where ":" ";
        $row = $this->db->getOne($sqlcmd);   
        if ($row===NULL || $row===false){   
            return $row;   
        }   
        if (is_array($row)){   
            return (int)current($row);   
        }   
        return (int)$row;   
//        if($result === false){
//			$this->err = "MC_Modle:(". __CLASS__ . ") 数据查询失败，请稍候再试 ( ".$this->db->getError()." )";
//            throw new MC_Exception($this->err);
//        }
//        return $result;
	}
	

	//锁表
	public function lock($rw="READ"){
        $this->db->lockTable( $this->tab,$rw);
	}
	//解锁表
	public function unlock(){
        $this->db->unlockTable($this->tab);
	}
	
	//返回表对应的字段
	public function getFields(){
		if(is_array($this->fields) && !empty($this->fields)){
			return $this->fields;
		}else if($this->tab != ''){
			$result = $this->db->query("DESCRIBE ".$this->tab);
			if(is_array($result) && !empty($result)){
				foreach ($result as $col){
					$this->fields[] = $col['Field'];
				}
				return $this->fields;
			}else if($result === false){
				$this->err = "MC_Modle:(". __CLASS__ . ") 数据库错误，请稍候再试 ( ".$this->db->getError()." )";
            	throw new MC_Exception($this->err);
			}
			return $result;
		}
	}
	
	//返回错误记录
	public function getError(){
		return $this->err;
	}


}




?>
